home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / blitter.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  13KB  |  473 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * Custom chip emulation
  5.   *
  6.   * (c) 1995 Bernd Schmidt, Alessandro Bissacco
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "gensound.h"
  15. #include "sounddep/sound.h"
  16. #include "events.h"
  17. #include "uae.h"
  18. #include "memory.h"
  19. #include "custom.h"
  20. #include "readcpu.h"
  21. #include "newcpu.h"
  22. #include "blitter.h"
  23. #include "blit.h"
  24.  
  25. uae_u16 bltsize, oldvblts;
  26. uae_u16 bltcon0,bltcon1;
  27. uae_u32 bltapt,bltbpt,bltcpt,bltdpt;
  28.  
  29. int blinea_shift;
  30. static uae_u16 blitlpos, blinea, blineb;
  31. static uaecptr bltcnxlpt,bltdnxlpt;
  32. static int blitline,blitfc,blitfill,blitife,blitdesc,blitsing;
  33. static int blitonedot,blitsign;
  34. static long int bltwait;
  35.  
  36. struct bltinfo blt_info;
  37.  
  38. static uae_u8 blit_filltable[256][4][2];
  39. uae_u32 blit_masktable[BLITTER_MAX_WORDS];
  40. static uae_u16 blit_trashtable[BLITTER_MAX_WORDS];
  41. enum blitter_states bltstate;
  42.  
  43. void build_blitfilltable(void)
  44. {
  45.     unsigned int d, fillmask;
  46.     int i;
  47.  
  48.     for (i = 0; i < BLITTER_MAX_WORDS; i++)
  49.     blit_masktable[i] = 0xFFFF;
  50.  
  51.     for (d = 0; d < 256; d++) {
  52.     for (i = 0; i < 4; i++) {
  53.         int fc = i & 1;
  54.         uae_u8 data = d;
  55.         for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) {
  56.         uae_u16 tmp = data;
  57.         if (fc) {
  58.             if (i & 2)
  59.             data |= fillmask;
  60.             else
  61.             data ^= fillmask;
  62.         }
  63.         if (tmp & fillmask) fc = !fc;
  64.         }
  65.         blit_filltable[d][i][0] = data;
  66.         blit_filltable[d][i][1] = fc;
  67.     }
  68.     }
  69. }
  70.  
  71. static __inline__ uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount)
  72. {
  73.     if (!chipmem_bank.check(bltpt,bytecount)) return NULL;
  74.     return chipmem_bank.xlateaddr(bltpt);
  75. }
  76.  
  77. static __inline__ uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount)
  78. {
  79.     if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL;
  80.     return chipmem_bank.xlateaddr(bltpt);
  81. }
  82.  
  83. static void blitter_dofast(void)
  84. {
  85.     int i,j;
  86.     uae_u8 *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
  87.     uae_u8 mt = bltcon0 & 0xFF;
  88.  
  89.     blit_masktable[0] = blt_info.bltafwm;
  90.     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
  91.  
  92.     if (bltcon0 & 0x800) {
  93.     bltadatpt = blit_xlateptr(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
  94.     bltapt += (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
  95.     }
  96.     if (bltcon0 & 0x400) {
  97.     bltbdatpt = blit_xlateptr(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
  98.     bltbpt += (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
  99.     }
  100.     if (bltcon0 & 0x200) {
  101.     bltcdatpt = blit_xlateptr(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
  102.     bltcpt += (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
  103.     }
  104.     if (bltcon0 & 0x100) {
  105.     bltddatpt = blit_xlateptr(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
  106.     bltdpt += (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
  107.     }
  108.  
  109.     if (blitfunc_dofast[mt] && !blitfill)
  110.     (*blitfunc_dofast[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
  111.     else {
  112.     uae_u32 blitbhold = blt_info.bltbhold;
  113.     uae_u32 preva = 0, prevb = 0;
  114.     uae_u16 foo, *dstp = &foo;
  115.  
  116.     /*if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt); */
  117.     for (j = 0; j < blt_info.vblitsize; j++) {
  118.         blitfc = !!(bltcon1 & 0x4);
  119.         for (i = 0; i < blt_info.hblitsize; i++) {
  120.         uae_u32 bltadat, blitahold;
  121.         if (bltadatpt) {
  122.             bltadat = do_get_mem_word((uae_u16 *)bltadatpt); bltadatpt += 2;
  123.         } else
  124.             bltadat = blt_info.bltadat;
  125.         bltadat &= blit_masktable[i];
  126.         blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift;
  127.         preva = bltadat;
  128.  
  129.         if (bltbdatpt) {
  130.             uae_u16 bltbdat = do_get_mem_word((uae_u16 *)bltbdatpt); bltbdatpt += 2;
  131.             blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift;
  132.             prevb = bltbdat;
  133.         }
  134.         if (bltcdatpt) {
  135.             blt_info.bltcdat = do_get_mem_word((uae_u16 *)bltcdatpt); bltcdatpt += 2;
  136.         }
  137.         do_put_mem_word(dstp, blt_info.bltddat);
  138.         blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
  139.         if (blitfill) {
  140.             uae_u16 d = blt_info.bltddat;
  141.             int ifemode = blitife ? 2 : 0;
  142.             int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
  143.             blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
  144.                     + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
  145.             blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
  146.         }
  147.         if (blt_info.bltddat) blt_info.blitzero = 0;
  148.         if (bltddatpt) {
  149.             dstp = (uae_u16 *)bltddatpt;
  150.             bltddatpt += 2;
  151.         }
  152.         }
  153.         if (bltadatpt) bltadatpt += blt_info.bltamod;
  154.         if (bltbdatpt) bltbdatpt += blt_info.bltbmod;
  155.         if (bltcdatpt) bltcdatpt += blt_info.bltcmod;
  156.         if (bltddatpt) bltddatpt += blt_info.bltdmod;
  157.     }
  158.     do_put_mem_word(dstp, blt_info.bltddat);
  159.     blt_info.bltbhold = blitbhold;
  160.     }
  161.     blit_masktable[0] = 0xFFFF;
  162.     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
  163.  
  164.     bltstate = BLT_done;
  165. }
  166.  
  167. static void blitter_dofast_desc(void)
  168. {
  169.     int i,j;
  170.     uae_u8 *bltadatpt = 0, *bltbdatpt = 0, *bltcdatpt = 0, *bltddatpt = 0;
  171.     uae_u8 mt = bltcon0 & 0xFF;
  172.  
  173.     blit_masktable[0] = blt_info.bltafwm;
  174.     blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
  175.  
  176.     if (bltcon0 & 0x800) {
  177.     bltadatpt = blit_xlateptr_desc(bltapt, (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize);
  178.     bltapt -= (blt_info.hblitsize*2+blt_info.bltamod)*blt_info.vblitsize;
  179.     }
  180.     if (bltcon0 & 0x400) {
  181.     bltbdatpt = blit_xlateptr_desc(bltbpt, (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize);
  182.     bltbpt -= (blt_info.hblitsize*2+blt_info.bltbmod)*blt_info.vblitsize;
  183.     }
  184.     if (bltcon0 & 0x200) {
  185.     bltcdatpt = blit_xlateptr_desc(bltcpt, (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize);
  186.     bltcpt -= (blt_info.hblitsize*2+blt_info.bltcmod)*blt_info.vblitsize;
  187.     }
  188.     if (bltcon0 & 0x100) {
  189.     bltddatpt = blit_xlateptr_desc(bltdpt, (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize);
  190.     bltdpt -= (blt_info.hblitsize*2+blt_info.bltdmod)*blt_info.vblitsize;
  191.     }
  192.     if (blitfunc_dofast_desc[mt] && !blitfill)
  193.     (*blitfunc_dofast_desc[mt])(bltadatpt,bltbdatpt,bltcdatpt,bltddatpt,&blt_info);
  194.     else {
  195.     uae_u32 blitbhold = blt_info.bltbhold;
  196.     uae_u32 preva = 0, prevb = 0;
  197.     uae_u16 foo, *dstp = &foo;
  198.  
  199. /*    if (!blitfill) fprintf(stderr, "minterm %x not present\n",mt);*/
  200.     for (j = 0; j < blt_info.vblitsize; j++) {
  201.         blitfc = !!(bltcon1 & 0x4);
  202.         for (i = 0; i < blt_info.hblitsize; i++) {
  203.         uae_u32 bltadat, blitahold;
  204.         if (bltadatpt) {
  205.             bltadat = do_get_mem_word((uae_u16 *)bltadatpt); bltadatpt -= 2;
  206.         } else
  207.             bltadat = blt_info.bltadat;
  208.         bltadat &= blit_masktable[i];
  209.         blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift;
  210.         preva = bltadat;
  211.         if (bltbdatpt) {
  212.             uae_u16 bltbdat = do_get_mem_word((uae_u16 *)bltbdatpt); bltbdatpt -= 2;
  213.             blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift;
  214.             prevb = bltbdat;
  215.         }
  216.         if (bltcdatpt) {
  217.             blt_info.bltcdat = do_get_mem_word((uae_u16 *)bltcdatpt); bltcdatpt -= 2;
  218.         }
  219.         do_put_mem_word(dstp, blt_info.bltddat);
  220.         blt_info.bltddat = blit_func(blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF;
  221.         if (blitfill) {
  222.             uae_u16 d = blt_info.bltddat;
  223.             int ifemode = blitife ? 2 : 0;
  224.             int fc1 = blit_filltable[d & 255][ifemode + blitfc][1];
  225.             blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0]
  226.                     + (blit_filltable[d >> 8][ifemode + fc1][0] << 8));
  227.             blitfc = blit_filltable[d >> 8][ifemode + fc1][1];
  228.         }
  229.         if (blt_info.bltddat) blt_info.blitzero = 0;
  230.         if (bltddatpt) {
  231.             dstp = (uae_u16 *)bltddatpt;
  232.             bltddatpt -= 2;
  233.         }
  234.         }
  235.         if (bltadatpt) bltadatpt -= blt_info.bltamod;
  236.         if (bltbdatpt) bltbdatpt -= blt_info.bltbmod;
  237.         if (bltcdatpt) bltcdatpt -= blt_info.bltcmod;
  238.         if (bltddatpt) bltddatpt -= blt_info.bltdmod;
  239.     }
  240.     do_put_mem_word(dstp, blt_info.bltddat);
  241.     blt_info.bltbhold = blitbhold;
  242.     }
  243.     blit_masktable[0] = 0xFFFF;
  244.     blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
  245.  
  246.     bltstate = BLT_done;
  247. }
  248.  
  249. static __inline__ int blitter_read(void)
  250. {
  251.     if (bltcon0 & 0xe00){
  252.     if (!dmaen(DMA_BLITTER)) return 1; /* blitter stopped */
  253.     if (bltcon0 & 0x200) blt_info.bltcdat = chipmem_bank.wget(bltcpt);
  254.     }
  255.     bltstate = BLT_work;
  256.     return (bltcon0 & 0xE00) != 0;
  257. }
  258.  
  259. static __inline__ int blitter_write(void)
  260. {
  261.     if (blt_info.bltddat) blt_info.blitzero = 0;
  262.     if ((bltcon0 & 0x100) || blitline){
  263.     if (!dmaen(DMA_BLITTER)) return 1;
  264.     chipmem_bank.wput(bltdpt, blt_info.bltddat);
  265.     }
  266.     bltstate = BLT_next;
  267.     return (bltcon0 & 0x100) != 0;
  268. }
  269.  
  270. static __inline__ void blitter_line_incx(void)
  271. {
  272.     if (++blinea_shift == 16) {
  273.     blinea_shift = 0;
  274.     bltcnxlpt += 2;
  275.     bltdnxlpt += 2;
  276.     }
  277. }
  278.  
  279. static __inline__ void blitter_line_decx(void)
  280. {
  281.     if (blinea_shift-- == 0) {
  282.     blinea_shift = 15;
  283.     bltcnxlpt -= 2;
  284.     bltdnxlpt -= 2;
  285.     }
  286. }
  287.  
  288. static __inline__ void blitter_line_decy(void)
  289. {
  290.     bltcnxlpt -= blt_info.bltcmod;
  291.     bltdnxlpt -= blt_info.bltcmod; /* ??? am I wrong or doesn't KS1.3 set bltdmod? */
  292.     blitonedot = 0;
  293. }
  294.  
  295. static __inline__ void blitter_line_incy(void)
  296. {
  297.     bltcnxlpt += blt_info.bltcmod;
  298.     bltdnxlpt += blt_info.bltcmod; /* ??? */
  299.     blitonedot = 0;
  300. }
  301.  
  302. static void blitter_line(void)
  303. {
  304.     uae_u16 blitahold = blinea >> blinea_shift, blitbhold = blineb & 1 ? 0xFFFF : 0, blitchold = blt_info.bltcdat;
  305.     blt_info.bltddat = 0;
  306.  
  307.     if (blitsing && blitonedot) blitahold = 0;
  308.     blitonedot = 1;
  309.     blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF);
  310.     if (!blitsign){
  311.     bltapt += (uae_s16)blt_info.bltamod;
  312.     if (bltcon1 & 0x10){
  313.         if (bltcon1 & 0x8)
  314.         blitter_line_decy();
  315.         else
  316.         blitter_line_incy();
  317.     } else {
  318.         if (bltcon1 & 0x8)
  319.         blitter_line_decx();
  320.         else
  321.         blitter_line_incx();
  322.     }
  323.     } else {
  324.     bltapt += (uae_s16)blt_info.bltbmod;
  325.     }
  326.     if (bltcon1 & 0x10){
  327.     if (bltcon1 & 0x4)
  328.         blitter_line_decx();
  329.     else
  330.         blitter_line_incx();
  331.     } else {
  332.     if (bltcon1 & 0x4)
  333.         blitter_line_decy();
  334.     else
  335.         blitter_line_incy();
  336.     }
  337.     blitsign = 0 > (uae_s16)bltapt;
  338.     bltstate = BLT_write;
  339. }
  340.  
  341. static __inline__ void blitter_nxline(void)
  342. {
  343.     bltcpt = bltcnxlpt;
  344.     bltdpt = bltdnxlpt;
  345.     blineb = (blineb << 1) | (blineb >> 15);
  346.     if (--blt_info.vblitsize == 0) {
  347.     bltstate = BLT_done;
  348.     } else {
  349.     bltstate = BLT_read;
  350.     }
  351. }
  352.  
  353. static void blit_init(void)
  354. {
  355.     blitlpos = 0;
  356.     blt_info.blitzero = 1;
  357.     blitline = bltcon1 & 1;
  358.     blt_info.blitashift = bltcon0 >> 12;
  359.     blt_info.blitdownashift = 16 - blt_info.blitashift;
  360.     blt_info.blitbshift = bltcon1 >> 12;
  361.     blt_info.blitdownbshift = 16 - blt_info.blitbshift;
  362.  
  363.     if (blitline) {
  364.     if (blt_info.hblitsize != 2) {
  365.         sprintf (warning_buffer, "weird hblitsize in linemode: %d\n", blt_info.hblitsize);
  366.         write_log (warning_buffer);
  367.     }
  368.     bltcnxlpt = bltcpt;
  369.     bltdnxlpt = bltdpt;
  370.     blitsing = bltcon1 & 0x2;
  371.     blinea = blt_info.bltadat;
  372.     blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16-blt_info.blitbshift));
  373. #if 0
  374.     if (blineb != 0xFFFF && blineb != 0)
  375.         fprintf(stderr, "%x %x %d %x\n", blineb, blt_info.bltbdat, blt_info.blitbshift, bltcon1);
  376. #endif
  377.     blitsign = bltcon1 & 0x40;
  378.     blitonedot = 0;
  379.     } else {
  380.     blitfc = !!(bltcon1 & 0x4);
  381.     blitife = bltcon1 & 0x8;
  382.     blitfill = bltcon1 & 0x18;
  383.     if ((bltcon1 & 0x18) == 0x18) {
  384.         /* Digital "Trash" demo does this; others too. Apparently, no
  385.          * negative effects. */
  386.         static int warn = 1;
  387.         if (warn)
  388.         write_log ("warning: weird fill mode (further messages suppressed)\n");
  389.         warn = 0;
  390.     }
  391.     blitdesc = bltcon1 & 0x2;
  392.     if (blitfill && !blitdesc)
  393.         write_log ("warning: blitter fill without desc\n");
  394.     }
  395. }
  396.  
  397. static void actually_do_blit(void)
  398. {
  399.     if (blitline) {
  400.     do {
  401.         blitter_read();
  402.         blitter_line();
  403.         blitter_write();
  404.         blitter_nxline();
  405.     } while (bltstate != BLT_done);
  406.     } else {
  407.     /*blitcount[bltcon0 & 0xff]++;  blitter debug */
  408.     if (blitdesc) blitter_dofast_desc();
  409.     else blitter_dofast();
  410.     }
  411.     blitter_done_notify ();
  412. }
  413.  
  414. void blitter_handler(void)
  415. {
  416.     if (!dmaen(DMA_BLITTER)) {
  417.     eventtab[ev_blitter].active = 1;
  418.     eventtab[ev_blitter].oldcycles = cycles;
  419.     eventtab[ev_blitter].evtime = 10 + cycles; /* wait a little */
  420.     return; /* gotta come back later. */
  421.     }
  422.     actually_do_blit();
  423.  
  424.     INTREQ(0x8040);
  425.     eventtab[ev_blitter].active = 0;
  426.     regs.spcflags &= ~SPCFLAG_BLTNASTY;
  427. }
  428.  
  429. void do_blitter(void)
  430. {
  431.     long int blit_cycles;
  432.     if (!currprefs.immediate_blits) {
  433.  
  434.     blit_cycles = 2;
  435.  
  436.     if (!blitline) {
  437.         if (bltcon0 & 0x400)
  438.         blit_cycles++;
  439.         if ((bltcon0 & 0x300) == 0x300)
  440.         blit_cycles++;
  441.         blit_cycles *= blt_info.vblitsize * blt_info.hblitsize;
  442.     }
  443.     } else
  444.     blit_cycles = 1;
  445.  
  446.     blit_init();
  447.  
  448.     eventtab[ev_blitter].active = 1;
  449.     eventtab[ev_blitter].oldcycles = cycles;
  450.     eventtab[ev_blitter].evtime = blit_cycles + cycles;
  451.     events_schedule();
  452.  
  453.     if (dmaen(DMA_BLITPRI))
  454.     regs.spcflags |= SPCFLAG_BLTNASTY;
  455. }
  456.  
  457. void maybe_blit(void)
  458. {
  459.     static int warned = 0;
  460.     if (bltstate == BLT_done)
  461.     return;
  462.  
  463.     if (!warned) {
  464.     warned = 1;
  465.     write_log ("warning: Program does not wait for blitter\n");
  466.     }
  467.     if (!eventtab[ev_blitter].active)
  468.     printf("FOO!!?\n");
  469.     actually_do_blit();
  470.     eventtab[ev_blitter].active = 0;
  471.     regs.spcflags &= ~SPCFLAG_BLTNASTY;
  472. }
  473.